package com.lsh.config;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;

import java.util.HashMap;
import java.util.Map;

/**
 * @author ：LiuShihao
 * @date ：Created in 2020/8/7 9:10 上午
 * @desc ：rabbitMQ配置类
 *
 * 1. 创建Queue队列                  ---->new Queue("myQueue1")
 * 2. 创建交换机FanoutExchange       ---->new FanoutExchange("myFanoutExchange")
 * 3. 将队列绑定到交换机上             --->BindingBuilder.bind(q3).to(myFanoutExchange)
 */
//@Configuration
public class RabbitMQConfig {
    @Bean
    @Qualifier("myQueue1")
    public Queue getQueue1(){
        return new Queue("myQueue1");//对列名:first
    }

    @Bean
    @Qualifier("myQueue2") // 都是Queue类型的,需要指定名字加以区分,不然无法注入
    public Queue getQueue2() {
        // 队列名1
        return new Queue("myQueue2");
    }

    @Bean
    @Qualifier("myQueue3")
    public Queue getQueue3() {
        // 队列名2
        return new Queue("myQueue3");
    }

    @Bean
    @Qualifier("myQueue4")
    public Queue getQueue4() {
        // 队列名3
        return new Queue("myQueue4");
    }
    /**
     * 创建交换机
     */
    @Bean(name = "myFanoutExchange")
    public FanoutExchange getFanoutExchange() {
        // 交换机名字
        return new FanoutExchange("myFanoutExchange");
    }

    /**
     * 队列绑定到交换机上
     */

    @Bean//将myQueue3队列绑定到myFanoutExchange这个交换机上
    public Binding bingding2(@Qualifier("myQueue3") Queue q2, @Qualifier("myFanoutExchange") FanoutExchange myFanoutExchange){
        return BindingBuilder.bind(q2).to(myFanoutExchange);
    }
    @Bean
    public Binding bingding3(@Qualifier("myQueue4") Queue q3,@Qualifier("myFanoutExchange") FanoutExchange myFanoutExchange){
        return BindingBuilder.bind(q3).to(myFanoutExchange);
    }
    @Bean
    @Qualifier("topic1")
    public Queue getMyQueue1() {
        // 队列名1
        return new Queue("topic1");
    }

    @Bean
    @Qualifier("topic2")
    public Queue getMyQueue2() {
        // 队列名2
        return new Queue("topic2");
    }

    @Bean
    @Qualifier("hw_data")
    public Queue getMyQueue3() {
        // 队列名3
        return new Queue("hw_data");
    }
    /**
     * 创建主题类型交换机
     */
    @Bean
    public TopicExchange getTopicExchange() {
        // 交换机名字
        return new TopicExchange("myTopicExchange");
    }
    /**
     * 队列绑定到交换机上,并且指定routingKey
     */
    @Bean
    public Binding bingding6(@Qualifier("topic1") Queue topic1, TopicExchange myTopicExchange){
        return BindingBuilder.bind(topic1).to(myTopicExchange).with("orders.#");
    }
    @Bean
    public Binding bingding4(@Qualifier("topic2") Queue topic2, TopicExchange myTopicExchange){
        return BindingBuilder.bind(topic2).to(myTopicExchange).with("#.log");
    }
    @Bean
    public Binding bingding5(@Qualifier("hw_data")Queue topic3,TopicExchange myTopicExchange){
        return BindingBuilder.bind(topic3).to(myTopicExchange).with("hw_data_key");
    }

    /**
     * 定义 Exchange 和 Queue
     * 定义交换机 confirmTestExchange 和队列 confirm_test_queue ，并将队列绑定在交换机上。
     * @return
     */
    @Bean(name = "confirmTestQueue")
    public Queue confirmTestQueue() {
        return new Queue("confirm_test_queue", true, false, false);
    }

    @Bean(name = "confirmTestExchange")
    public FanoutExchange confirmTestExchange() {
        return new FanoutExchange("confirmTestExchange");
    }

    @Bean
    public Binding confirmTestFanoutExchangeAndQueue(
            @Qualifier("confirmTestExchange") FanoutExchange confirmTestExchange,
            @Qualifier("confirmTestQueue") Queue confirmTestQueue) {
        return BindingBuilder.bind(confirmTestQueue).to(confirmTestExchange);
    }



    //延时交换机
    public static final String DELAY_EXCHANGE_NAME = "delayExchange";

    //延时队列
    public static final String DELAY_QUEUEA_NAME = "delayQueueA";

    //延时队列路由key
    public static final String DELAY_QUEUEA_ROUTING_KEY = "delayQueueAroutingkey";

    //死信交换机
    public static final String DELAY_LETTER_EXCHANGE = "deadLetterExchange";

    //死信队列路由key
    public static final String DELAY_LETTER_QUEUEA_ROUTING_KEY = "deadLetterQueueAroutingkey";

    //死信队列
    public static final String DELAY_LETTER_QUEUEA_NAME = "deadLetterQueueA";

    /**
     * 实现延时队列的思路：
     * 生产者生产消息
     * 通过 延时队列路由key  经过  延时交换机   发送到  延时队列
     * 延时队列中的消息过期以后
     * 通过 死信队列路由key 经过  死信交换机  进入死信队列
     * 消费者监听死信队列进行消费
     */

    // 延时交换机
    @Bean("delayExchange")
    public DirectExchange delayExchange(){
        return new DirectExchange("delayExchange");
    }

    // 死信交换机
    @Bean("deadLetterExchange")
    public DirectExchange deadLetterExchange(){
        return new DirectExchange("deadLetterExchange");
    }

    /**
     * 死信队列A            用于接收延时10s处理的消息
     * @return
     */
    @Bean("deadLetterQueueA")
    public Queue deadLetterQueueA(){
        return new Queue("deadLetterQueueA");
    }

    /**
     * 延时队列A        延时6s
     * 并绑定到对应的死信交换机
     * @return
     */
    @Bean("delayQueueA")
    public Queue delayQueueA(){
        Map<String, Object> args = new HashMap<>(2);
        // x-dead-letter-exchange    这里声明当前队列绑定的死信交换机
        args.put("x-dead-letter-exchange", "deadLetterExchange");
        // x-dead-letter-routing-key  这里声明当前队列的死信路由key
        args.put("x-dead-letter-routing-key", "deadLetterQueueAroutingkey");
        // x-message-ttl  声明队列的TTL
        args.put("x-message-ttl", 6000);
        return QueueBuilder.durable("delayQueueA").withArguments(args).build();
    }


    /**
     * 将延时队列A与延时交换机绑定   并指定延时队列路由
     * @param queue
     * @param exchange
     * @return
     */
    @Bean
    public Binding delayBindingA(@Qualifier("delayQueueA") Queue queue,
                                 @Qualifier("delayExchange") DirectExchange exchange){
        return BindingBuilder.bind(queue).to(exchange).with("delayQueueAroutingkey");
    }

    /**
     * 将死信队列 与 死信交换机绑定   指定死信队列路由
     * @param queue
     * @param exchange
     * @return
     */
    @Bean
    public Binding deadLetterBindingA(@Qualifier("deadLetterQueueA") Queue queue,
                                      @Qualifier("deadLetterExchange") DirectExchange exchange){
        return BindingBuilder.bind(queue).to(exchange).with("deadLetterQueueAroutingkey");
    }








}
